<!DOCTYPE html>
<html>
    <head>
        <title>Point Cloud Viewer</title>

        <style type="text/css">
            #info {
                color: black;
                position: absolute;
                top: 0;
                left: 0;
                margin-left: 15px;
                padding: 0.3rem;
                background-color: white;
                border: 2px solid black;
                border-radius: 5px;
            }

            .centered {
                margin-left: auto;
                margin-right: auto;
                max-width: 25rem;
                border: 2px solid black;
                padding: 1rem;
                background: rgba(128, 168, 197, 1);
                border-radius: 5px;
                display: none;
            }

            #viewerDiv {
                display: none;
            }

            input {
                margin-top: 1rem;
                font-size: 1rem;
            }

            #url {
                width: calc(100% - 1rem);
            }

            #submit {
                margin-left: 25%;
                margin-right: 25%;
                width: 50%;
            }

            /* lopocs result display */
            table {
                margin-top: 3rem;
                width: 100%;
                border-collapse: collapse;
            }
            th, td {
                padding: 0.3rem;
                text-align: center;
            }
            tr:nth-child(even) {
                background-color: #c6cfd5;
            }
            tr:nth-child(odd) {
                background-color: #9fc0d5;
            }
            #result {
                display: none;
            }
            @media (max-width: 600px) {
                #info,
                .dg {
                    display: none;
                }
            }
        </style>

        <meta charset="UTF-8">
        <link rel="stylesheet" type="text/css" href="css/example.css">
        <link rel="stylesheet" type="text/css" href="css/loading_screen.css">

        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <div id="viewerDiv">
            <div id="info"></div>
        </div>

        <div class="centered">
            <div id="lopocs"> </div>
            <div id="itowns"> </div>
            <h2>Point cloud absolute URL: </h2>
            <h4>(file.js from PotreeConverter or Lopocs url)</h4>
            <input id="url" type="url" value="https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/eglise_saint_blaise_arles/eglise_saint_blaise_arles.js">
            <input id="submit" type="submit" value="Connect">
            <div id="result">
                <h3>Available pointclouds:</h3>
                <table id="dropdown"></table>
            </div>

            <!-- POINTCLOUD TABLE SELECTION -->
            <script type="text/javascript">
                function createResultRow(serverUrl, table) {
                    var tr = document.createElement('tr');
                    var td = document.createElement('td');
                    td.textContent = table;
                    var td2 = document.createElement('td');
                    var i = document.createElement('input');
                    i.value = 'Display';
                    i.type = 'submit';

                    function onDisplayClicked() {
                        showPointcloud(serverUrl, undefined, table, false);
                    }

                    i.addEventListener('click', onDisplayClicked);

                    td2.appendChild(i);
                    tr.appendChild(td);
                    tr.appendChild(td2);
                    return tr;
                }

                function buildLopocsResultTable(serverUrl, metadata) {
                    document.getElementById('result').style.display = 'block';
                    var dd = document.getElementById('dropdown');
                    // clean table
                    while (dd.firstChild) {
                        dd.removeChild(dd.firstChild);
                    }
                    var i;
                    for (i = 0; i < metadata.length; i++) {
                        dd.appendChild(createResultRow(serverUrl, metadata[i].table));
                    }
                }

                function onConnectClicked() {
                    var url = document.getElementById('url').value;

                    // assume that "url ends with .js" == potreeconverter
                    // no .endsWith() in ES5...
                    if (url.indexOf('.js') === (url.length - 3)) {
                        var lastSlashIndex = url.lastIndexOf('/');
                        var filename = url.substr(lastSlashIndex + 1);

                        showPointcloud(url.substr(0, lastSlashIndex), filename, undefined, true);
                    } else {
                        itowns.Fetcher.json(url + '/infos/sources').then(function(meta) { buildLopocsResultTable(url, meta); });
                    }
                }
            </script>
            <script src="js/GUI/dat.gui/dat.gui.min.js"></script>
            <script src="../dist/itowns.js"></script>
            <script src="js/loading_screen.js"></script>
            <script src="../dist/debug.js"></script>
            <script type="text/javascript">
                var searchParams = new URL(window.location.href).searchParams;
                function showPointcloud(serverUrl, fileName, lopocsTable) {
                    var pointcloud;
                    var oldPostUpdate;
                    var viewerDiv;
                    var debugGui;
                    var view;
                    var controls;

                    viewerDiv = document.getElementById('viewerDiv');
                    viewerDiv.style.display = 'block';

                    itowns.THREE.Object3D.DefaultUp.set(0, 0, 1);

                    debugGui = new dat.GUI({ width: 400 });

                    // TODO: do we really need to disable logarithmicDepthBuffer ?
                    view = new itowns.View('EPSG:3946', viewerDiv);
                    setupLoadingScreen(viewerDiv, view);
                    view.mainLoop.gfxEngine.renderer.setClearColor(0xcccccc);

                    // Configure Point Cloud layer
                    pointcloud = new itowns.GeometryLayer('eglise_saint_blaise_arles', new itowns.THREE.Group());
                    pointcloud.file = fileName || 'infos/sources';
                    pointcloud.protocol = 'potreeconverter';
                    pointcloud.url = serverUrl;
                    pointcloud.table = lopocsTable;
                    if (searchParams.get('material') === 'three') {
                        pointcloud.material = new itowns.THREE.PointsMaterial({
                            color: 0xff8888,
                            sizeAttenuation: false,
                            size: 1,
                            vertexColors: itowns.THREE.VertexColors
                        });
                    }

                    // point selection on double-click
                    function dblClickHandler(event) {
                        var pick = view.pickObjectsAt(event, 5, pointcloud);

                        for (const p of pick) {
                            console.info('Selected point #' + p.index + ' in position (' +
                                p.object.position.x + ', ' +
                                p.object.position.y + ', ' +
                                p.object.position.z +
                             ') in Points ' + p.object.layer.id);
                        }
                    }
                    view.mainLoop.gfxEngine.renderer.domElement.addEventListener('dblclick', dblClickHandler);


                    function placeCamera(position, lookAt) {
                        view.camera.camera3D.position.set(position.x, position.y, position.z);
                        view.camera.camera3D.lookAt(lookAt);
                        // create controls
                        controls = new itowns.FirstPersonControls(view, { focusOnClick: true });
                        debugGui.add(controls.options, 'moveSpeed', 1, 100).name('Movement speed');

                        view.notifyChange(view.camera.camera3D);
                    }

                    // add pointcloud to scene
                    function onLayerReady() {
                        var ratio;
                        var position;
                        var lookAt = new itowns.THREE.Vector3();
                        var size = new itowns.THREE.Vector3();

                        pointcloud.root.bbox.getSize(size);
                        pointcloud.root.bbox.getCenter(lookAt);

                        debug.PointCloudDebug.initTools(view, pointcloud, debugGui);

                        view.camera.camera3D.far = 2.0 * size.length();

                        ratio = size.x / size.z;
                        position = pointcloud.root.bbox.min.clone().add(
                            size.multiply({ x: 0, y: 0, z: ratio * 0.5 }));
                        lookAt.z = pointcloud.root.bbox.min.z;
                        placeCamera(position, lookAt);
                        controls.moveSpeed = size.length() / 3;

                        // update stats window
                        oldPostUpdate = pointcloud.postUpdate;
                        pointcloud.postUpdate = function postUpdate() {
                            var info = document.getElementById('info');
                            oldPostUpdate.apply(pointcloud, arguments);
                            info.textContent = 'Nb points: ' +
                                pointcloud.displayedCount.toLocaleString();
                        };
                    }
                    window.view = view;

                    view.addLayer(pointcloud).then(onLayerReady);
                }

                if (searchParams.get('selector')) {
                    document.getElementsByClassName('centered')[0].style.display = 'block';
                    document.getElementById('submit').addEventListener('click', onConnectClicked);
                } else {
                    onConnectClicked();
                }
            </script>
    </body>
</html>

